using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace Tester.GuiActions.Actions
{
    public class ActionsManager
    {
        public delegate void IterActionDelegate(IAction action);

        public const string DEFAULT_ACTION_NAMESPACE = "Tester.GuiActions.Actions.Impl";

        private Dictionary<string, IAction> _actions = new Dictionary<string, IAction>();

        public void AddAction(XmlReader reader, string actionName, string className)
        {
            IAction newAction = CreateActionInstance(actionName, className);
            _actions.Add(actionName, newAction );
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        {
                            if (reader.Name == "Appearence")
                            {
                                readActionAppearence(reader, newAction);
                            }
                            else if (reader.Name == "Description")
                            {
                                newAction.Description = reader.ReadString();
                                if (!reader.IsEmptyElement)
                                {
                                    reader.ReadEndElement();
                                }
                            }
                        }
                        break;
                    case XmlNodeType.EndElement:
                        return;
                    default:
                        break;
                }
            }
        }

        private void readActionAppearence(XmlReader reader, IAction action)
        {
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        {
                            switch (reader.Name)
                            {
                                case "MainMenu":
                                    string menuName;
                                    reader.MoveToAttribute("item");
                                    menuName = reader.Value;
                                    Actions.Instance.MainMenuManager.AddAction(menuName, action);
                                    break;
                                case "ToolBar":
                                    string barName;
                                    reader.MoveToAttribute("member");
                                    barName = reader.Value;
                                    action.AddToolBar(barName);
                                    break;
                                case "Context":
                                    string contextName;
                                    string contextDisplay;
                                    reader.MoveToAttribute("name");
                                    contextName = reader.Value;
                                    reader.MoveToAttribute("display");
                                    contextDisplay = reader.Value;
                                    action.AddContext(contextName, contextDisplay); 
                                    break;
                                case "UIEvent":
                                    string eventName;
                                    reader.MoveToAttribute("event");
                                    eventName = reader.Value;
                                    action.AddUIEvent(eventName); 
                                    break;
                            }
                            reader.MoveToElement();
                            if (!reader.IsEmptyElement)
                            {
                                reader.ReadEndElement();
                            }
                            break;
                        }
                    case XmlNodeType.EndElement:
                        return;
                    default:
                        break;
                }
            }
        }

        private IAction CreateActionInstance(string actionName, string className)
        {
            string fullClassName;
            if (actionName.IndexOf('.') >0 )
            {
                fullClassName = className;
            } else
            {
                fullClassName = DEFAULT_ACTION_NAMESPACE + '.' + className;
            }
            Type instanceType = Type.GetType(fullClassName, true, true);
            IAction instance = (IAction)Activator.CreateInstance(instanceType);
            instance.Name = actionName; 
            return instance; 
        }

        public IAction ActionByName(string name)
        {
            IAction ret;
            _actions.TryGetValue(name, out ret);
            return ret;
        }

        public IAction ActionByToolBarName(string name)
        {
            foreach (KeyValuePair<string, IAction> pair in _actions)
            {
                if (pair.Value.ToolBarName == name)
                {
                    return pair.Value;
                }
            }
            return null;
        }

        public void Iter(IterActionDelegate method)
        {
            foreach (KeyValuePair<string, IAction> pair in _actions)
            {
                method.Invoke(pair.Value);
            }
        }
    }
}
